import random
import re
from datetime import datetime

from flask import current_app
from flask import make_response, jsonify
from flask import request
from flask import session

from info import constants, db
from info import redis_store
from info.lib.sms import CCP
from info.models import User
from info.modules.passport import passport
from info.response_code import RET
from info.utils.captcha.captcha import captcha


@passport.route('/logout')
def logout():
    session.pop('user_id', None)
    session.pop('mobile', None)
    session.pop('nick_name', None)
    session.pop('is_admin', None)

    # 为了防止管理员误入前台，留下is_admin状态保持信息，所以不管谁在退出登录，都要把is_admin清理
    session.pop('is_admin', False)
    return jsonify(errno=RET.OK, errmsg='退出成功！')


@passport.route('/login', methods=['POST'])
def login():
    """
     登陆：
     1.获取参数
     2.校验参数，非空校验
     3.匹配用户名是否存在
     4.校验密码
     5.讲用户信息保存在session中

    :return:
    """
    # 获取参数
    request_data = request.json
    mobile = request_data.get('mobile')
    password = request_data.get('password')

    # 校验非空
    if not all([mobile, passport]):
        return jsonify(errno=RET.DATAERR, errmsg='参数不完整')
    # 校验用户名是否存在
    try:
        user = User.query.filter(User.nick_name == mobile).first()
    except Exception as e:
        current_app.logging.error(e)
        return jsonify(errno=RET.DBERR, errmsg='查询用户名失败')

    if not user:
        return jsonify(errno=RET.NODATA, errmsg='用户未注册')

    # 校验密码
    if not user.check_passowrd(password):
        return jsonify(errno=RET.PWDERR, errmsg='密码错误')

        # 将用户信息存在session中
    session['user_id'] = user.id
    session['mobile'] = user.mobile
    session['nick_name'] = user.nick_name

    user.update_time = datetime.now()

    return jsonify(errno=RET.OK, errmsg='登陆成功！')


@passport.route('/register', methods=['POST'])
def register():
    """
    1.获取参数
    2.校验参数 非空
    3.校验手机号码
    4.校验短信验证码
    5.保存密码
    6.记录用户信息在session中
    :return:
    """
    request_data = request.json
    mobile = request_data.get('mobile')
    password = request_data.get('password')
    sms_code = request_data.get('smscode')
    # 非空校验
    if not all([mobile, passport, sms_code]):
        return jsonify(errno=RET.DATAERR, errmsg='参数不完整')

    # 校验手机号码
    if not re.match(r'1[3456789]\d{9}', mobile):
        return jsonify(errno=RET.DATAERR, errmsg='手机不合法')

    # 从redis中获取手机短信验证码
    try:
        sms_code = redis_store.get('sms:%s' % mobile)
    except Exception as e:
        current_app.logging.error(e)
        return jsonify(errno=RET.DBERR, errmsg='短信验证码获取失败')

    # 判断验证码是否有效
    if not sms_code:
        return jsonify(errno=RET.DATAERR, errmsg='手机验证码失效')

    # 新增用户信息
    user = User()
    user.nick_name = mobile
    user.password = password
    user.mobile = mobile

    try:
        db.session.add(user)
        db.session.commit()
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='保存用户信息失败')

    return jsonify(errno=RET.OK, errmsg='注册成功')


@passport.route('/sms_code', methods=['POST'])
def send_msg():
    """
    1.获取参数
    2.校验参数 非空校验
    3.校验手机号码
    4.从redis中获取图片验证码
    5.校验图片验证码
    6.发送短信验证码
    7.将短信验证码存在redis中
    8.返回响应
    :return:
    """
    # 获取参数
    request_data = request.json

    moblie = request_data.get('mobile')
    img_code = request_data.get('image_code')
    img_code_id = request_data.get('image_code_id')

    # 非空校验
    if not all([moblie, img_code, img_code_id]):
        return jsonify(errno=RET.NODATA, errmsg="参数不完成")
    # 校验手机号码
    if not re.match(r'1[3456789]\d{9}', moblie):
        return jsonify(errno=RET.DATAERR, errmsg='手机不合法')

    # 从redis中获取图片校验码
    try:
        img_data = redis_store.get('img:%s' % img_code_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='查询图片验证码失败')

    # 校验图片验证码是否过期
    if not img_data:
        return jsonify(errno=RET.DATAERR, errmsg='图片验证码已过期')
    # 校验图片验证码是否正确
    if img_code.lower() != img_data.lower():
        return jsonify(errno=RET.DATAERR, errmsg='图片验证码输入有误')

    # 发送短信验证码
    # 编辑短信内容
    sms_code = '%06d' % random.randint(0, 999999)

    # 发送短信
    # try:
    #     result = CCP().send_template_sms(moblie, [sms_code, int(constants.SMS_CODE_REDIS_EXPIRES / 30)], 1)
    # except Exception as e:
    #     current_app.logging(e)
    #     return jsonify(errno=RET.NODATA, errmsg='发送短信异常')
    # # 校验短信是否成功
    # if result == -1:
    #     return jsonify(errno=RET.NODATA, errmsg='发送短信验证码失败')
    # 将短信验证码保存在redis中
    current_app.logger.debug(sms_code)
    try:
        redis_store.set('sms:%s' % moblie, sms_code, constants.SMS_CODE_REDIS_EXPIRES)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='保存短信验证码失败')
    # 返回响应
    return jsonify(errno=RET.OK, errmsg='短信验证码发送成功')


@passport.route('/get_img')
def img_code():
    # 获取参数
    img_code = request.args.get('img_code')
    pre_code = request.args.get('pre_code')
    # 画图片验证码
    name, text, image = captcha.generate_captcha()
    # 将图片验证码存在redis中
    redis_store.set('img:%s' % img_code, text, constants.IMAGE_CODE_REDIS_EXPIRES)
    if pre_code:
        redis_store.delete('img:%s' % pre_code)
    resp = make_response(image)
    resp.headers['Content-Type'] = 'img/png'
    return resp
